package com.woniuxy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.common.ConstantData;
import com.woniuxy.common.RedisKey;
import com.woniuxy.controller.form.StoreInfoSearchForm;
import com.woniuxy.controller.form.StoreInfoUpdateForm;
import com.woniuxy.controller.form.StoreInfoUpdateStatusForm;
import com.woniuxy.dao.FoodTypeMapper;
import com.woniuxy.dao.FoodVarietyMapper;
import com.woniuxy.entity.FoodType;
import com.woniuxy.entity.FoodVariety;
import com.woniuxy.entity.StoreInfo;
import com.woniuxy.dao.StoreInfoMapper;
import com.woniuxy.exception.parameter.storeInfo.StoreInfoException;
import com.woniuxy.exception.parameter.storeInfo.StoreInfoExceptionCode;
import com.woniuxy.service.FoodTypeService;
import com.woniuxy.service.FoodVarietyService;
import com.woniuxy.service.StoreInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.service.dto.*;
import com.woniuxy.util.EsUtil;
import com.woniuxy.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zz
 * @since 2023年06月13日
 */
@Service
public class StoreInfoServiceImpl extends ServiceImpl<StoreInfoMapper, StoreInfo> implements StoreInfoService {

    @Autowired
    private StoreInfoMapper mapper;
    @Autowired
    private FoodVarietyService foodVarietyService;
    @Autowired
    private FoodVarietyMapper foodVarietyMapper;
    @Autowired
    private FoodTypeService foodTypeService;
    @Resource
    private StringRedisTemplate template;
    @Resource
    private ElasticsearchRestTemplate esTemplate;
    @Resource
    private RedisUtil redisUtil;

    /**
     * 更新商家基本信息
     * @param form
     * @param accountId
     * @return
     */
    @Override
    public StoreInfo updateMessage(StoreInfoUpdateForm form, Integer accountId) {
        StoreInfo storeInfo1 = mapper.selectOne(new QueryWrapper<StoreInfo>().eq("accountId", accountId));
        //更新名称同步更新菜品表中商铺名称  从redis中查找所有菜品id
        if(form.getStoreName()!=null || form.getStoreName().equals("")){
            StoreInfo storeName = mapper.selectOne(new QueryWrapper<StoreInfo>().eq("storeName", form.getStoreName()).ne("id",storeInfo1.getId()));
            if(storeName!=null){
                throw new StoreInfoException(StoreInfoExceptionCode.STORE_NAME_IS_EXIST);
            }
            List<FoodVariety> food = foodVarietyMapper.selectList(new QueryWrapper<FoodVariety>().eq("storeId", storeInfo1.getId()));
            if(food!=null && food.size()>0){
                for (FoodVariety foodVariety : food) {
                    foodVariety.setStoreName(form.getStoreName());
                    foodVarietyService.saveOrUpdate(foodVariety);
                }
            }

        }
        StoreInfo storeInfo = BeanUtil.toBean(form, StoreInfo.class);
        storeInfo.setId(storeInfo1.getId());
        storeInfo.setAccountId(accountId.longValue());
        //更新商铺表
        this.saveOrUpdate(storeInfo);
        //更新es
        StoreInfoForEsDto storeInfoForEsDto = BeanUtil.toBean(storeInfo, StoreInfoForEsDto.class);
        esTemplate.save(storeInfoForEsDto);
        return storeInfo;
    }

    @Override
    public WoniuPageDto<StoreInfoForAdminDto> searchByCondition(StoreInfoSearchForm form) {
        Page<StoreInfo> page = new Page<>(form.getCurrent() == null ? 1 : form.getCurrent(), form.getSize() == null ? 3 : form.getSize());
        QueryWrapper<StoreInfo> wrapper = new QueryWrapper<>();
        if(form.getStatus()!=null ){
            wrapper.eq("status",form.getStatus()).eq("deleteFlag", ConstantData.STATE_NORMAL);
        }
        if(form.getStoreStatus()!=null){
            wrapper.eq("storeStatus",form.getStoreStatus()).eq("deleteFlag",ConstantData.STATE_NORMAL);
        }
        if(form.getStoreName()!=null){
            wrapper.eq("storeName",form.getStoreName());
        }
        if(form.getStatus()==null && form.getStoreStatus()==null){
            wrapper.eq("deleteFlag",ConstantData.STATE_NORMAL);
        }
        mapper.selectPage(page,wrapper);
        if(page.getRecords().size()==0 || page.getRecords()==null){
            throw new StoreInfoException(StoreInfoExceptionCode.STORES_IS_NOT_EXIST);
        }
        ArrayList<StoreInfoForAdminDto> dtos = new ArrayList<>();
        for (StoreInfo storeInfo : page.getRecords()) {
            StoreInfoForAdminDto dto = BeanUtil.toBean(storeInfo, StoreInfoForAdminDto.class);
            if(storeInfo.getStatus()==ConstantData.STORE_INFO_STATUS_FREEZE){
                dto.setStatusName("冻结中");
            }else if(storeInfo.getStatus()==ConstantData.STORE_INFO_STATUS_LIVE){
                dto.setStatusName("已激活");
            }
            if(storeInfo.getStoreStatus()==ConstantData.STORE_INFO_STATUS_OPEN){
                dto.setStoreStatusName("开业中");
            }else if(storeInfo.getStoreStatus()==ConstantData.STORE_INFO_STATUS_REST){
                dto.setStoreStatusName("歇业中");
            }
            //添加该商家经营的所有菜品类型;
//            dto.setTypeNames();
            Set<String> foodIds = template.opsForZSet().range(RedisKey.getStoreFoods(storeInfo.getId().toString()), 0, -1);


            dtos.add(dto);
        }
        WoniuPageDto woniuPageDto = BeanUtil.toBean(page, WoniuPageDto.class);
        woniuPageDto.setList(dtos);
        return woniuPageDto;
    }

    @Override
    public void updateStatus(StoreInfoUpdateStatusForm form) {

        StoreInfo storeInfo = mapper.selectById(form.getId());
        if(storeInfo==null){
            throw new StoreInfoException(StoreInfoExceptionCode.STORE_IS_NOT_EXIST);
        }
        if(form.getDeleteFlag()!=null){ //删除商铺
            storeInfo.setDeleteFlag(ConstantData.STATE_DEL);
            StoreInfoForEsDto storeInfoForEsDto = BeanUtil.toBean(storeInfo, StoreInfoForEsDto.class);
            esTemplate.delete(storeInfoForEsDto);
        }else{ //冻结/激活商铺
            if(form.getStatus()==storeInfo.getStatus() && form.getStatus()==ConstantData.STORE_INFO_STATUS_FREEZE){
                throw new StoreInfoException(StoreInfoExceptionCode.STORE_STATUS_FREEZE_ED);
            }
            if(form.getStatus()==storeInfo.getStatus() && form.getStatus()==ConstantData.STORE_INFO_STATUS_LIVE){
                throw new StoreInfoException(StoreInfoExceptionCode.STORE_STATUS_LIVE_ED);
            }
            storeInfo.setStatus(form.getStatus());
            if(form.getStatus()==ConstantData.STORE_INFO_STATUS_FREEZE){
                storeInfo.setRemarks(form.getRemarks());
            }
            storeInfo.setUpdateDate(LocalDateTime.now());
            storeInfo.setStoreStatus(ConstantData.STORE_INFO_STATUS_REST);//冻结了就歇业
        }
        this.saveOrUpdate(storeInfo);
    }

    @Override
    public void updateStatusByOwner(Integer storeStatus, Integer accountId) {
        QueryWrapper<StoreInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("accountId",accountId);
        StoreInfo storeInfo = mapper.selectOne(wrapper);
        if(storeInfo==null){
            throw new StoreInfoException(StoreInfoExceptionCode.STORE_IS_NOT_EXIST);
        }
        if(storeStatus==storeInfo.getStoreStatus() && storeStatus==ConstantData.STORE_INFO_STATUS_REST){
            throw new StoreInfoException(StoreInfoExceptionCode.STORE_STATUS_REST_ED);
        }
        if(storeStatus==storeInfo.getStoreStatus() && storeStatus==ConstantData.STORE_INFO_STATUS_OPEN){
            throw new StoreInfoException(StoreInfoExceptionCode.STORE_STATUS_OPEN_ED);
        }
        storeInfo.setStoreStatus(storeStatus);
        storeInfo.setUpdateDate(LocalDateTime.now());
        this.saveOrUpdate(storeInfo);
    }

    @Override
    public StoreInfoForOwnerDto get(Integer accountId) {
        QueryWrapper<StoreInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("accountId",accountId).eq("deleteFlag",ConstantData.STATE_NORMAL);
        StoreInfo storeInfo = mapper.selectOne(wrapper);
        if(storeInfo==null){
            throw new StoreInfoException(StoreInfoExceptionCode.STORE_IS_NOT_EXIST);
        }
        StoreInfoForOwnerDto dto = BeanUtil.toBean(storeInfo, StoreInfoForOwnerDto.class);
        if(storeInfo.getStatus()==ConstantData.STORE_INFO_STATUS_FREEZE){
            dto.setStatusName("已冻结");
        }else{
            dto.setStatusName("已激活");
        }
        if(storeInfo.getStoreStatus()==ConstantData.STORE_INFO_STATUS_OPEN){
            dto.setStoreStatusName("开业中");
        }else{
            dto.setStoreStatusName("歇业中");
        }
        return dto;
    }

    @Override
    public StoreInfo getByAccountId(Integer accountId) {
        return this.lambdaQuery().eq(StoreInfo::getAccountId, accountId).one();
    }

    @Override
    public List<CategoryDto> getCategories(Integer accountId) {
        StoreInfo storeInfo = this.getByAccountId(accountId);
        Long storeInfoId = storeInfo.getId();
        return baseMapper.listCategories(storeInfoId);
    }

    @Override
    public List<CategoryDto> getCategories() {
        List<FoodType> foodTypes = foodTypeService.lambdaQuery()
                .select(FoodType::getId, FoodType::getTypeName)
                .eq(FoodType::getTypeSelf, 1)
                .eq(FoodType::getTypeState,1).list();
        return foodTypes.stream().map(CategoryDto::from).collect(Collectors.toList());
    }
}
